package com.erp.freight.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.erp.freight.domain.ErpProductArea;
import com.erp.freight.domain.ErpProductFreight;
import com.erp.freight.domain.bo.ErpProductFreightBo;
import com.erp.freight.domain.vo.ErpLogisticsServiceInfoVo;
import com.erp.freight.domain.vo.ErpProductFreightVo;
import com.erp.freight.domain.vo.ErpProductRefinementFreightVo;
import com.erp.freight.service.IErpCommonProductFreightService;
import com.erp.freight.service.IErpProductFreightService;
import com.erp.freight.service.IErpUpdateFreightTemplateService;
import com.ruoyi.common.core.annotation.RepeatSubmit;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.JsonUtils;
import com.ruoyi.common.core.utils.oldUtils.StringUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.web.oldController.BaseController;
import com.ruoyi.common.core.web.oldPage.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.freight.api.domain.AeProductFreight;
import com.ruoyi.freight.api.domain.ErpProductExistingFreightRecord;
import com.ruoyi.gather.api.RemoteGatherProductService;
import com.ruoyi.gather.api.domain.ErpCollectProduct;
import com.ruoyi.gather.api.domain.ErpCollectProductExpand;
import com.ruoyi.gather.api.domain.ErpCollectProductSku;
import com.ruoyi.gather.api.domain.ErpProductArea64;
import com.ruoyi.gather.api.domain.dto.ComputeFreightDto;
import com.ruoyi.system.api.RemoteDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 运费试算模版（各物流公司运费格读取）
 *
 * @author erp
 * @date 2023-06-23
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/freight")
public class ErpProductFreightController extends BaseController {

    private final IErpProductFreightService iErpProductFreightService;
    private final IErpCommonProductFreightService commonProductFreightService;

    private final RemoteDictDataService remoteDictDataService;
    private final RemoteGatherProductService remoteGatherProductService;
//    private final IErpSellerProductService erpSellerProductService;
//    private final IErpCollectProductExpandService erpCollectProductExpandService;

    private final IErpUpdateFreightTemplateService updateFreightTemplateService;

    /**
     * 查询运费试算模版（各物流公司运费格读取）列表
     */
//    @SaCheckPermission("system:productFreight:list")
    @GetMapping("/list")
    public TableDataInfo<ErpProductFreightVo> list(ErpProductFreightBo bo, PageQuery pageQuery) {
        return iErpProductFreightService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出运费试算模版（各物流公司运费格读取）列表
     */
//    @SaCheckPermission("system:productFreight:export")
    @Log(title = "运费试算模版（各物流公司运费格读取）", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(ErpProductFreightBo bo, HttpServletResponse response) {
        List<ErpProductFreightVo> list = iErpProductFreightService.queryList(bo);
        ExcelUtil<ErpProductFreightVo> util = new ExcelUtil<ErpProductFreightVo>(ErpProductFreightVo.class);
        util.exportExcel(response, list, "运费试算模版（各物流公司运费格读取）", "运费试算模版");
    }

    /**
     * 获取运费试算模版（各物流公司运费格读取）详细信息
     *
     * @param id 主键
     */
//    @SaCheckPermission("system:productFreight:query")
    @GetMapping("/{id}")
    public R<ErpProductFreightVo> getInfo(@NotNull(message = "主键不能为空")
                                          @PathVariable Long id) {
        return R.ok(iErpProductFreightService.queryById(id));
    }

    /**
     * 新增运费试算模版（各物流公司运费格读取）
     */
//    @SaCheckPermission("system:productFreight:add")
    @Log(title = "运费试算模版（各物流公司运费格读取）", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody ErpProductFreightBo bo) {
        return toAjax(iErpProductFreightService.insertByBo(bo));
    }

    /**
     * 修改运费试算模版（各物流公司运费格读取）
     */
//    @SaCheckPermission("system:productFreight:edit")
    @Log(title = "运费试算模版（各物流公司运费格读取）", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ErpProductFreightBo bo) {
        return toAjax(iErpProductFreightService.updateByBo(bo));
    }

    /**
     * 删除运费试算模版（各物流公司运费格读取）
     *
     * @param ids 主键串
     */
//    @SaCheckPermission("system:productFreight:remove")
    @Log(title = "运费试算模版（各物流公司运费格读取）", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(iErpProductFreightService.deleteWithValidByIds(Arrays.asList(ids), true));
    }

    /**
     * 运费试算
     *
     * @param erpProductExistingFreightRecord
     * @return
     */
    @PostMapping("/calculateFreight")
    public R<Object> calculateFreight(@RequestBody ErpProductExistingFreightRecord erpProductExistingFreightRecord) {
        // TODO 原AeProductFreight表中缺少商品属性：0普货、1特货（非普货）、2大包，其中大包根据计算获取，入参只需要提供是普货还是非普货即可

        // 判断是否是大包
//        boolean isBale = iErpProductFreightService.judgeBaleProduct(aeProductFreight);

        // TODO 根据是大包、普货、非普货，以及国家、体积、重量等信息，获取是否有完全一致的记录，没有则计算，有直接获取

        // 没有匹配数据，重新试算
        BigDecimal calculateFreightByCaiNiao = commonProductFreightService.freightTrialByCaiNiao(erpProductExistingFreightRecord);
        if (calculateFreightByCaiNiao == null) {
            return R.fail("暂无服务");
        }

        return R.ok(calculateFreightByCaiNiao);
    }


    /**
     * 推荐物流方案
     *
     * @param erpProductExistingFreightRecord
     * @return
     */
    @PostMapping("/recommended/logistics")
    public R<Object> recommendedLogisticsRoutes(@RequestBody ErpProductExistingFreightRecord erpProductExistingFreightRecord) {
//        if (aeProductFreight.getCountry().equals("UK")){
//            aeProductFreight.setCountry("GB");
//        }
        R<String> dictLabelResult = remoteDictDataService.getDictLabel("ae_country_code", erpProductExistingFreightRecord.getCountry(), SecurityConstants.INNER);
        if (R.FAIL == dictLabelResult.getCode()) {
            throw new ServiceException(dictLabelResult.getMsg());
        }
        if (dictLabelResult.getData() != null && !dictLabelResult.getData().equals("")) {
            erpProductExistingFreightRecord.setCountry(dictLabelResult.getData());
        }
        // 没有匹配数据，重新试算
        List<ErpLogisticsServiceInfoVo> list = commonProductFreightService.getRecommendedLogisticsRoutes(erpProductExistingFreightRecord);
        if (list.size() == 0) {
            return R.fail("暂无服务");
        }

        return R.ok(list);
    }

    /**
     * 64国运费试算
     *
     * @param aeProductFreight
     * @return
     */
    @PostMapping("/freightTrialWith64")
    public R<Object> freightTrialWith64(@RequestBody AeProductFreight aeProductFreight) {
        List<AeProductFreight> list = commonProductFreightService.freightTrialWith64(aeProductFreight);
        List<Map<String, Object>> collect = list.stream().map(vo -> {
            Map<String, Object> map = new HashMap<>();
            map.put("lable", vo.getFreight());
            map.put("value", vo.getCountry());
            return map;
        }).collect(Collectors.toList());

        return R.ok(collect);
    }

    @PostMapping("/computeFreightWith64")
    public R<Object> computeFreightWith64(@RequestBody ComputeFreightDto dto) {

        Map<String, Double> cacheMap = new HashMap<String, Double>();

        // 获取国家
//        List<ErpProductArea64> selectList = area64Mapper.selectList();
        // 判断是哪种产品
        R<Object> objectR = remoteGatherProductService.queryArea64List();
        String data = JSONObject.toJSONString(objectR.getData());
        List<ErpProductArea64> selectList = JSONArray.parseArray(data,ErpProductArea64.class);
//        List<ErpProductArea64> selectList = (List<ErpProductArea64>) objectR.getData();
        // 获取商品
        ErpCollectProduct collectProduct = JSONObject.parseObject(dto.getProduct().toString(), ErpCollectProduct.class);
        // 获取扩展信息
        ErpCollectProductExpand collectProductExpand = JSONObject.parseObject(dto.getProductExpand().toString(), ErpCollectProductExpand.class);
        //获取sku信息
        List<ErpCollectProductSku> skuList = JSONArray.parseArray(dto.getProductSkuList().toJSONString(), ErpCollectProductSku.class);

        // 获取商品的属性 TODO 目前只区分普货和特货，大包时时计算，新增新的类型后，需要修改该判断方式

        Integer templateId = Objects.isNull(collectProductExpand.getTemplateId()) ? 0 : collectProductExpand.getTemplateId();

        List<Object> list = new ArrayList<Object>();
        // 获取采集商品sku
        for (ErpProductArea64 erpProductArea : selectList) {

            String areaNo = erpProductArea.getAreaNo();

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("shiptoCountry", areaNo);
            if (areaNo.equals("GB"))
                map.put("shiptoCountry", "UK");

            Map<String, Double> skuMap = new HashMap<String, Double>();
            for (ErpCollectProductSku erpCollectProductSku : skuList) {
                String skuLength = Objects.isNull(erpCollectProductSku.getSkuLength()) ? "10" : erpCollectProductSku.getSkuLength().toString();
                String skuWidth = Objects.isNull(erpCollectProductSku.getSkuWidth()) ? "10" : erpCollectProductSku.getSkuWidth().toString();
                String skuHeight = Objects.isNull(erpCollectProductSku.getSkuHeight()) ? "10" : erpCollectProductSku.getSkuHeight().toString();
                String skuWeight = Objects.isNull(erpCollectProductSku.getSkuWeight()) ? collectProduct.getGrossWeight().toString() : erpCollectProductSku.getSkuWeight().toString();

                // 获取sku标识
                String skuPropertyIds = erpCollectProductSku.getSkuPropertyIds();

                String key = skuWeight + "-" + skuWidth + "-" + skuHeight + "-" + skuLength + "-" + "-" + skuLength
                        + "-" + areaNo;

                // 首先获取缓存map有值吗sku
                Double priceCalculator = cacheMap.get(key);
                if (priceCalculator != null) {
                    skuMap.put(skuPropertyIds, priceCalculator);
                } else {
                    AeProductFreight aeProductFreight = new AeProductFreight();
                    aeProductFreight.setCountry(areaNo);
                    aeProductFreight.setWeight(skuWeight);
                    aeProductFreight.setHeight(skuHeight);
                    aeProductFreight.setWidth(skuWidth);
                    aeProductFreight.setLength(skuLength);
                    // 类型：标准0、特货1、纯电2、大包3等，参考字典表erp_product_template
                    aeProductFreight.setType(templateId);

                    // 首先获取数据库中是否有记录
//						AeProductFreight aeProductFreight = aeProductFreightMapper.selectOne(
//								new LambdaQueryWrapper<AeProductFreight>().eq(AeProductFreight::getLength, skuLength)
//										.eq(AeProductFreight::getWeight, skuWeight)
//										.eq(AeProductFreight::getHeight, skuHeight)
//										.eq(AeProductFreight::getWidth, skuWidth)
//										.eq(AeProductFreight::getType, productAttribute)
//										.eq(AeProductFreight::getCountry, areaNo).last(" limit 1 "));
//						if (aeProductFreight != null) {
//							priceCalculator = aeProductFreight.getFreight().doubleValue();
//						} else {

                    BigDecimal calculateFreightByCaiNiao = commonProductFreightService
                            .freightTrialByCaiNiao(aeProductFreight);
                    if (calculateFreightByCaiNiao != null)
                        priceCalculator = calculateFreightByCaiNiao.doubleValue();
                    else {
                        return R.fail("运费试算失败");
                    }
                    if (!priceCalculator.equals(0d)) {

                        // 增加10%的费用
                        priceCalculator = new BigDecimal(priceCalculator * 1.1)
                                .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    }
                    skuMap.put(skuPropertyIds, priceCalculator);
                    cacheMap.put(key, priceCalculator);

                }
            }
            map.put("absoluteQuoteMap", skuMap);
            list.add(map);
        }

        collectProductExpand.setFreightMap(JsonUtils.toJsonString(list));
        collectProductExpand.setIsFreight(3); // 计算完成

        dto.setProduct(JSONObject.parseObject(JSONObject.toJSONString(collectProduct)));
        dto.setProductExpand(JSONObject.parseObject(JSONObject.toJSONString(collectProductExpand)));
        dto.setProductSkuList(JSONArray.parseArray(JSONObject.toJSONString(skuList)));
        return R.ok(dto);
    }


    /**
     * 精细化计算运费模版
     */
    @PostMapping("/export/freight/template")
    public void exportFreightTemplateStandard(HttpServletResponse response) {
        /**
         * 1-标准普货，2-经济普货，3-标准大包，4-大包专线，5-标准特货，6-经济特货，7-特货专线-标准，8-菜鸟特货专线-标快
         */
        // 大包模版（大包专线-标准）--共用
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("4", null,"RMB"),
//                "大包模版（大包专线-标准）", ErpProductRefinementFreightVo.class, response);
        // 大包模版（菜鸟标准-大包）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("3", "4","RMB"),
//                "大包模版（菜鸟标准-大包）", ErpProductRefinementFreightVo.class, response);
        // 标准模版（菜鸟标准-普货）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("1", null, "RMB"),
//                "标准模版（菜鸟标准-普货）", AEProductRefinementFreightVo.class, response);
        // 标准模版（大包专线）--共用，同大包模版（菜鸟标准-大包）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("4", "3","RMB"),
//                "标准模版（大包专线）", ErpProductRefinementFreightVo.class, response);
        // 标准模版（菜鸟标准大包）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("3", "1","RMB"),
//                "标准模版（菜鸟标准-大包）", ErpProductRefinementFreightVo.class, response);
        // 标准模版（菜鸟大包专线）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("4", "1","RMB"),
//                "标准模版（菜鸟大包专线）", ErpProductRefinementFreightVo.class, response);
        // 特货模版（菜鸟特货专线－标准）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("7", null,"RMB"),
//                "特货模版（菜鸟特货专线－标准）", ErpProductRefinementFreightVo.class, response);
        // 特货模版（菜鸟特货专线-标快）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("8", "7", "RMB"),
//                "特货模版（菜鸟特货专线-标快）", ErpProductRefinementFreightVo.class, response);
        // 特货模版（菜鸟标准-大包）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("3", "7", "RMB"),
//                "特货模版（菜鸟标准-大包）", ErpProductRefinementFreightVo.class, response);
        // 特货模版（标准-大包专线）
        ExcelUtil<ErpProductRefinementFreightVo> util = new ExcelUtil<ErpProductRefinementFreightVo>(ErpProductRefinementFreightVo.class);
        util.exportExcel(response, commonProductFreightService.calculateRefinementFreightTemplate("4", "7", "RMB"),
                "特货模版（标准-大包专线）", "特货模版（标准-大包专线）");
        // 经济普通模版（菜鸟超级经济Global）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("2", null,"RMB"),
//                "经济普通模版（菜鸟超级经济Global）", ErpProductRefinementFreightVo.class, response);
        // 经济特货模版（菜鸟特货专线－超级经济）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("6", null,"RMB"),
//                "经济特货模版（菜鸟特货专线－超级经济）", ErpProductRefinementFreightVo.class, response);
        // 经济普通模版（菜鸟标准-普货）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("1", "2","RMB"),
//                "经济普通模版（菜鸟标准-普货）", ErpProductRefinementFreightVo.class, response);
        // 经济普通模版（菜鸟标准-普货）
//        ExcelUtil.exportExcel(commonProductFreightService.calculateRefinementFreightTemplate("7", "6","RMB"),
//                "经济普通模版（菜鸟特货专线－标准）", ErpProductRefinementFreightVo.class, response);


        // 临时用，导出100g以内每10克的标准普货和经济普货的价格差，标准特货和经济特货的价格差
//        ExcelUtil.exportExcel(commonProductFreightService.calculatePriceDifference(),
//                "价格差", ErpProductRefinementFreightVo.class, response);
    }

    @GetMapping("/getCountryList")
    public R<Object> getCountryList() {
        List<ErpProductFreight> list = iErpProductFreightService.countryList();
        List<Map<String, Object>> collect = list.stream().map(vo -> {
            Map<String, Object> map = new HashMap<>();
            map.put("lable", vo.getCountryCode());
            map.put("value", vo.getCountry());
            return map;
        }).collect(Collectors.toList());
        return R.ok(collect);
    }

    /**
     * 临时方法，根据个人产品库里的2.0商品，更新采集库中的状态为上架
     * @return
     */
//    @GetMapping("/updateProduct20Status")
//    public R<Void> updateProduct20Status() {
//        // 获取个人产品库里的2.0商品
//        List<ErpSellerProduct> sellerProductList = erpSellerProductService.getErpSellerProduct20();
//        // 根据采集ID，更新采集库状态
//        int i = 0;
//        int j = 0;
//        for (ErpSellerProduct erpSellerProduct: sellerProductList){
//            if (erpCollectProductExpandService.updateProductStatusById(null, erpSellerProduct.getCollectProductId(), 1)){
//                i++;
//            }else {
//                j++;
//            }
//        }
//        System.out.println(i + ":" + j);
//        return toAjax(i);
//    }
}
